package br.org.reconcavotecnologia.update19.registro.engine;

import java.io.IOException;
import java.util.List;

import br.org.reconcavotecnologia.update19.network.Download;
import br.org.reconcavotecnologia.update19.network.UtilProxy;

/**
 * Mecanismo para realizar as ações do sistema sobre os arquivos. (Download, Remoção, Atualizaçã e Ações especiais)
 * 
 * @author Cássio Oliveira
 *
 */
public class MaquinaAcao {

	/** Sistemas operacionais suportados */
	private static final int LINUX = 1;

	/** Indicação do tipo de ação a ser executada */
	public static final int  DOWNLOAD = 0, ATUALIZA = 1, REMOVER = 2;
	
	/** Sistema operacional atual */
	private int so;

	/** Cabeçalho do servidor de dados */
	private String serverPath = null;

	/** Representa uma lista de ações. Sua é composta de ações com o tipo e lista de parametros definidos */
	private List<Acao> listaAcoes = null;
	
	/** Método construtor. Define o cabeçalho do servidor de dados */
	public MaquinaAcao(String serverPath) {
		this.serverPath = serverPath;
		this.defineSO();
	}
	
	/** Adiciona uma acao a lista de acoes a serem executadas.*/
	public void addAcao(Acao acao){
		this.listaAcoes.add(acao);
	}

	/** Faz o download de um arquivo e o salva com o mesmo nome*/
	public void download(String newSource){
		this.download(newSource, newSource);
	}

	/** Faz o download de um arquivo e o salva com um nome específico */
	public void download(String newSource, String targetName){
		// configura o download passando como parametro o início do caminho do
		// servidor concatenado com o caminho relativo do arquivo a ser baixado
		// e o nome do arquivo de destino
		Download d = new Download(serverPath + "/" +newSource, targetName);
		try {
			// tenta realizar o download, passando o proxy adequado
			d.start(UtilProxy.getProxy());
			// aguarda a execução do download
			d.waitFor();
		} catch (Exception e) {
			System.err.println("Update19.runClientSide() Erro ao fazer download");
			e.printStackTrace();
		}
	}

	/** Processa as ações cadastrada na lista de ações */
	public void executarAcoes(){
		for (Acao acao : listaAcoes) {
			switch (acao.getTipoAcao()) {
			case ATUALIZA:
				this.atualiza((String)(acao.getListaParametro().get(0)), (String)(acao.getListaParametro().get(1)));
				break;
			case DOWNLOAD:
				this.download((String)(acao.getListaParametro().get(0)));
				break;
			case REMOVER:
				this.remove((String)(acao.getListaParametro().get(0)));
				break;
			default:
				break;
			}
		}
	}
	
	/**
	 *  Realiza o update de um arquivo.
	 *  TODO É necessário realizar o download do arquivo em uma pasta temporária, antes de fazer a substituição
	 */
	public void atualiza(String source, String target){
		this.remove(source);
		this.download(target);
	}

	/** Remove um arquivo */
	public void remove(String source){
		switch (so) {
		case LINUX:
			try {
				Runtime.getRuntime().exec("rm -rf " + source);
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		default:
			System.err.println("MaquinaAcao.remove() este comando não está implementado para sua plataforma. Implemente-o e tente novamente.");
			break;
		}
	}

	/** Move um arquivo de um diretório para outro */
	public void move(String source, String target){
		switch (so) {
		case LINUX:
			try {
				Runtime.getRuntime().exec("mv " + source + " " + target);
			} catch (IOException e) {
				e.printStackTrace();
			}
			break;
		default:
			System.err.println("MaquinaAcao.remove() este comando não está implementado para sua plataforma. Implemente-o e tente novamente.");
			break;
		}
	}

	/** Define o sistema operacional uttilizado */
	private void defineSO(){
		this.so = 1;
	}

	/** Método para teste da classe */
	public static void main(String[] args) {
		MaquinaAcao ma = new MaquinaAcao("http://update19.googlecode.com/svn/trunk/update19/docs/");
		ma.download("update.info?last");
	}
	
}